package com.moyz.adi.common.annotation;

import com.moyz.adi.common.validator.AskReqValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.*;


/**
 * AskReqCheck 是一个自定义的 Bean 验证注解，用于验证 {@link com.moyz.adi.common.dto.AskReq} 对象。
 * 它指定了一个或多个验证器（如 AskReqValidator.class）来实现特定的验证逻辑。
 */
@Constraint(validatedBy = {
        AskReqValidator.class, // 指定用于验证 AskReq 对象的验证器类
})
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE})
//@Retention(RetentionPolicy.RUNTIME) 是 Java 的元注解之一，用于指定自定义注解的保留策略（即生命周期）。
// 它决定了编译器和运行时环境如何处理该注解。
// 具体来说，RetentionPolicy.RUNTIME 表示该注解会在编译后保留，并且可以在运行时通过反射访问。
/**
 * RetentionPolicy.SOURCE：
注解仅保留在源代码级别，在编译时被丢弃，不会出现在 .class 文件中。
适用于那些只需要在编译期间提供信息的注解，例如一些编译时检查或生成代码的工具。
 * RetentionPolicy.CLASS：
注解会编译到 .class 文件中，但在加载类时由 JVM 丢弃，不会保留在内存中。
适用于那些需要在类加载期间进行某些操作的注解，但不需要在运行时访问。
 * RetentionPolicy.RUNTIME：
注解不仅会被编译到 .class 文件中，还会在运行时由 JVM 保留，可以通过反射访问。
适用于那些需要在运行时动态读取和处理的注解，例如框架中的依赖注入、日志记录、事务管理等。
 **/
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时保留，可以通过反射访问
@Documented // 注解将被包含在生成的 Java 文档中
public @interface AskReqCheck {

    /**
     * 默认的错误消息。当验证失败且没有提供具体的消息时，使用此默认值。
     *
     * @return 默认错误消息
     */
    String message() default "请求参数验证失败"; // 修改默认消息以更好地描述验证失败的情况

    /**
     * 验证组。可以用来分组不同的验证规则，以便在不同场景下执行不同的验证逻辑。
     *
     * @return 验证组数组
     */
    Class<?>[] groups() default {};

    /**
     * 附加的元数据（负载），可以在验证过程中传递与验证相关的上下文信息。
     *
     * @return 负载类数组
     */
    Class<? extends Payload>[] payload() default {};
}
